package com.example.concurrent.chapter10;

/**
 * @author Liuqz
 * @date 2018/11/24 21:52
 */
public class NameSpace {

    /**
     * 类的加载就是将class文件中的二进制数据读取到内存中,然后将该字节流所代表的静态存储结构转换为方法区中运行时的数据结构,并且在堆内存中生成一个java.lang.Class对象,作为访问方法区数据结构的入口
     *
     * 类加载的最终产物就是堆内存中的class对象,对同一个ClassLoader来讲,不管某个类被加载了多少次,对应到堆内存中的class对象始终是同一个
     *
     * result : 1950409828
     *          1950409828
     *          true
     * @param args
     * @throws ClassNotFoundException
     */

    //使用同一个加载器去加载
    /*public static void main(String[] args) throws ClassNotFoundException {
        //获取系统类加载器
        ClassLoader classLoader = NameSpace.class.getClassLoader();

        Class<?> aClass = classLoader.loadClass("com.example.concurrent.chapter10.Test");

        Class<?> bClass = classLoader.loadClass("com.example.concurrent.chapter10.Test");

        System.out.println(aClass.hashCode());
        System.out.println(bClass.hashCode());
        System.out.println(aClass == bClass);
    }*/


    //使用不同的加载器加载类
    /*public static void main(String[] args) throws ClassNotFoundException {
        MyClassLoader classLoader1 = new MyClassLoader("E:\\classloader1", null);
        BrokerDelegateClassLoader classLoader2 = new BrokerDelegateClassLoader("E:\\classloader1", null);

        Class<?> aClass = classLoader1.loadClass("com.example.concurrent.chapter10.Test");
        Class<?> bClass = classLoader2.loadClass("com.example.concurrent.chapter10.Test");

        System.out.println(aClass.getClassLoader());
        System.out.println(bClass.getClassLoader());
        System.out.println(aClass.hashCode());
        System.out.println(bClass.hashCode());
        System.out.println(aClass == bClass);
    }*/

    //相同类加载器加载同一个class
    public static void main(String[] args) throws ClassNotFoundException {
        MyClassLoader classLoader1 = new MyClassLoader("E:\\classloader1", null);
        MyClassLoader classLoader2 = new MyClassLoader("E:\\classloader2", null);

        Class<?> aClass = classLoader1.loadClass("com.example.concurrent.chapter10.Test");
        Class<?> bClass = classLoader2.loadClass("com.example.concurrent.chapter10.Test");

        System.out.println(aClass.getClassLoader());
        System.out.println(bClass.getClassLoader());
        System.out.println(aClass.hashCode());
        System.out.println(bClass.hashCode());
        System.out.println(aClass == bClass);

    }

    /**
     * 同一个class实例只能在JVM中存在一份这样的说法是不够严谨的
     * 更准确的说法应该是 : 同一个class实例在同一个类加载器命名空间之下是唯一的
     */
}
